-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Incorporate variance into typeck #12828
Conversation
The travis errors look a little suspicious, but they may be spurious, just making sure that you managed to get past stage1 locally. |
It did. All the way to the |
Cool, thanks! |
r? me -- @edwardw sorry for being incommunicado, I've been heads down on unrelated things and was planning to come back to your questions this week, but I see you've made great progress on your own. |
I'm not sure about the changes to inference with the nullary type. I agree it's surprising, but completely consistent, that |
The current patch makes no effort to discriminate nullary type from others; it simply add covariant constraint to type parameters for all types, used or unused. As for lifetime parameters, I'll try to add constraints to them, too. |
By adding contravariant constraint to all lifetime parameters, we make rust more rigorous. For example, json.rs#L318 is now rejected: pub fn buffer_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~[u8] {
//Serialize the object in a string using a writer
let mut m = MemWriter::new();
{
let mut encoder = Encoder::new(&mut m as &mut io::Writer); // `m` does not live long enough
to_encode_object.encode(&mut encoder);
}
m.unwrap()
} |
@edwardw Sorry, I'm confused. Why would we add a covariant constraint to all type parameters? And why would we add contravariant to all lifetimes? That seems clearly wrong. For example, a type like:
Should be contravariant in |
As discussed in IRC, this is just another bug. The lifetime parameter and mutability in a trait reference are never used in variance inference. So the patch ends up always adding constraints for them which leads to noticeable behavior change. |
I was driving by this (just taking a look), and noticed that transmutes are popping up in what I thought was completely safe code. Is the current code unsound? |
I assume you asked about the last commit about librustdoc. Strangely enough, without the additional transmute, there is LLVM assertion failure. |
Not just that, but also the "Fix fallout for stage1" commit. Fixing an LLVM assertion failure with a transmute sounds... dubious |
Oh, that's because a bug in the variance inference that didn't take lifetime parameter and mutability of a trait reference into consideration, which is now fixed. If taking a close look, Yes, this is a behavior change and is open for discussion. |
I'm not entirely certain how much this relates to rust-lang/rfcs#12, but if this has semantic changes I think it should go through an RFC before merging. I still don't understand why transmutes are popping up as fallout of this change, nor why the tests had to change. I'm not entirely certain what's going on here though, so if these are soundness changes than that's fine, but unfortunate. |
The commit that fixes pub struct Encoder<'a> {
priv wr: &'a mut io::Writer,
} as if it were pub struct Encoder<'a> {
priv wr: & io::Writer,
} In my opinion this is a soundness issue. I couldn't find a way to fix As for the variance RFC, it asks to add constraints for unused type parameters only. The The transmute introduced in |
On Wed, Mar 19, 2014 at 01:20:13PM -0700, Edward Wang wrote:
Yes.
Probably we will have to refactor json.rs. This happens sometimes. Alex is definitely right though -- there should be no need for transmutes and so forth. |
I'd like to close this PR. It has changed scope several times. The |
This can break code that looked like: impl Foo for Box<Any> { fn f(&self) { ... } } let x: Box<Any + Send> = ...; x.f(); Change such code to: impl Foo for Box<Any> { fn f(&self) { ... } } let x: Box<Any> = ...; x.f(); That is, upcast before calling methods. This is a conservative solution to rust-lang#5781. A more proper treatment (see the xfail'd `trait-contravariant-self.rs`) would take variance into account. This change fixes the soundness hole. Some library changes had to be made to make this work. In particular, `Box<Any>` is no longer showable, and only `Box<Any+Send>` is showable. Eventually, this restriction can be lifted; for now, it does not prove too onerous, because `Any` is only used for propagating the result of task failure. This patch also adds a test for the variance inference work in rust-lang#12828, which accidentally landed as part of DST. Closes rust-lang#5781. [breaking-change]
… borrows still in scope". This issue was fixed by PR rust-lang#12828 and rust-lang#5781. All that was left was to add tests. Closes rust-lang#12223.
… r=Veykril Rename proc macro server from 'Rustc' to 'RustAnalyzer' Related to: * rust-lang/rust-analyzer#12818 This is mostly a courtesy PR for the sake of rustc maintainers. When they looked at `proc-macro-srv`, they noticed the server was named `Rustc` — probably because of historical copy-paste. Only rustc's proc macro server should be named `Rustc`, ra's can be named `RustAnalyzer`. Maintainer impact: There's no semantic changes in this PR, only naming. One test snapshot was updated since "proc macro server types" were used to test traits somewhere else and I renamed those too, why not.
Currently, rustc only does so for regions substitution. Applies the same
rule to type and self parameter substitution.
With all three substitutions on, the following becomes legitimate:
x
here is contravariant with respect to the region parameterb
, soit is eligible to the return position, also contravariant.
It is also found that rustc handled one special case incorrectly. In
variance inference pass, constraints are added and then solved. But rustc
didn't add any constraint for nullary generic enum and struct so they
were classified as bivariant, the default. Then the following two
implementations of
Foo
:would be identical therefor conflicting under type substitution, which
is incorrect.
Closes #3598.
Closes #5781.